package com.jd.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.jwt.crypto.sign.MacSigner;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import java.util.List;

/**
 * @author wangshuping
 * @version 1.0
 * @date 2021/11/15 22:38
 * 每个服务都是资源服务器，需要携带token访问
 */
@EnableResourceServer
@Slf4j
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    /**
     * jwt 对称加密密钥
     */
    @Value("${spring.security.oauth2.jwt.signingKey:123456}")
    private String signingKey;

    /**
     * 不需要认证的路径
     */
    private static final String[] PERMIT_ALL_URIS = {"/v2/api-docs",
            //用来获取支持的动作
            "/swagger-resources/configuration/ui",
            //用来获取api-docs的URI
            "/swagger-resources",
            //安全选项
            "/swagger-resources/configuration/security",
            "/webjars/**",
            "/doc.html",
            "/swagger-ui.html",
            //不对springboot-admin监控的请求进行权限校验
            "/actuator/**",
            //不对springboot-admin监控的实例信息请求进行权限校验;
            "/instances/**",
            "/authorization-server/oauth/token",
            "/login",
            "/admin-service/login"
    };

    @Override
    public void configure(HttpSecurity http) throws Exception {
        //使用JWT，不需要csrf
        http.csrf().disable()
                .sessionManagement().disable()
                .authorizeRequests().antMatchers(PERMIT_ALL_URIS).permitAll()
                .antMatchers("/**").authenticated()
                .and().headers().cacheControl();
    }


    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(jwtTokenStore());
    }

    private TokenStore jwtTokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    private JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();
        tokenConverter.setSigningKey(signingKey);
        tokenConverter.setVerifier(new MacSigner(signingKey));
        return tokenConverter;
    }
}
